<?php
/**
 * This file is part of DomAr.
 * 
 * DomAr is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * DomAr is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with DomAr.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * @link http://inditel.ee/
 * @copyright 2007-2009 Inditel Meedia OÜ
 * @author Oliver Leisalu <oliver@inditel.ee>
 */

/**
* @package DomAr
* @subpackage Parser
*/
class DomArClassParserListener {
	
	/**
	 * Some sample values are beforeset, beforeinsert, afterdelete etc..
	 * 
	 * @var String Listener type 
	 */
	private $type;
	/**
	 * Method that will be called.
	 *
	 * @var String
	 */
	private $method;
	/**
	 * Args that will be given as arguments to that method.
	 *
	 * @var String
	 */
	private $args;
	/**
	 * If this is set listener is considered to be property listener.
	 *
	 * @var String Property name to which this listener is attached.
	 */
	private $propertyName;
	/**
	 * Property name to which method is called.
	 * If set to __record, then method is called to record object.
	 * 
	 * @var String
	 */
	private $target = '__record';
	/**
	 * If true method will be called to property handler.
	 * Basicly in class self::getProperty($this->target)->{$this->method}()
	 * 
	 * NB! Target has to be set to use this!
	 * @var bool
	 */
	private $callPropertyHandler = false;
	/**
	 * @var DomArClassParserListener
	 */
	private $className;
	
	
	/**
	 * @param String $type
	 * @param String $method
	 * @param Mixed $args
	 */
	public function __construct( $type, $method, $args ) {
		$this->type = strtolower($type);
		$this->method = $method;
		$this->setArgs( $args );
	}
	/**
	 * Sets args. Can be String or Array.
	 * Array will be converted to PHP Array String.
	 * 
	 * @param Mixed $args
	 */
	public function setArgs( $args ) {
		if( is_array($args) ) {
			$argsStr = '';
			foreach( $args as $argu ) {
				if( is_numeric( $argu ) )
					$argsStr .= ','.$argu;
				else if ( is_string( $argu ) )
					$argsStr .= ',\''.$argu.'\'';
				else if (is_array( $argu ) )
					$argsStr .= ','.self::arrayToPhpFunctionArgs($argu);
			}
			$args = &$argsStr;
		}
		$this->args = (string)$args;
	}
	/**
	 * @param String $target
	 */
	public function setTarget( $target ) {
		$this->target = $target;
	}
	/**
	 * @param String $propertyName
	 */
	public function setPropertyName( $propertyName ) {
		$this->propertyName = $propertyName;
	}
	/**
	 * @param Bool $value
	 */
	public function setCallPropertyHandler( $value ) {
		$this->callPropertyHandler = (bool)$value;
	}
	/**
	 * @var String $className
	 */
	public function setClassName( $className ) {
		$this->className = $className;
	}
	/**
	 * @return DomArClassParser
	 */
	public function getClass() {
		return DomArClassParser::get($this->className);
	}
	/**
	 * @param String $var
	 * @return Mixed
	 */
	public function __get( $var ) {
		return $this->$var;
	}
	/**
	 * @return String
	 */
	public function getPhpCode() {
		
		// beforeset and beforevalidate need different syntax
		if( in_array($this->type, array('beforeset','beforevalidate')) === true ) {
			
			if( $this->callPropertyHandler === false) {
				if( $this->target == '__record') {
					$this->getClass()->checkListenerMethod( $this->method );
				}
				$target = $this->target !== '__record' ? $this->target.'->' : NULL;
				return '$this->'.$target.$this->method.'( $value '.$this->args.' );'."\n";
			
			} else {
				return 'self::getProperty(\''.$this->target.'\')->'.$this->method.'( $this, $value, \''.$this->propertyName.'\' '.$this->args.' );'."\n";
			}
			
		// other internal listeners
		} else if( in_array($this->type, array('beforeinsert','afterinsert','beforesave','aftersave','beforeupdate','afterupdate','beforedelete','afterdelete','afterset')) === true ) {
			
			if( $this->callPropertyHandler === false) {
				if( $this->target == '__record') {
					$this->getClass()->checkListenerMethod( $this->method );
				}
				$target = $this->target !== '__record' ? $this->target.'->' : NULL;
				return '$this->'.$target.$this->method.'( '.substr($this->args,1).' );'."\n";
			
			} else {
				return 'self::getProperty(\''.$this->target.'\')->'.$this->method.'( $this, '.$this->propertyName.' '.$this->args.' );'."\n";
			}
			
		// plugin listener
		} else {
			
			return 'self::$properties[\''.$this->propertyName.'\']->registerListener(\''.$this->type.'\',\''.$this->method.'\',array('.substr($this->args,1).'));';
			
		}		
	}
}
?>